using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

namespace SpriteLib
{
    public class Sprite : ISprite
    {

        private List<ISprite> childSprites = new List<ISprite>();
        private List<ISpriteEffect> spriteEffects = new List<ISpriteEffect>();
        protected Vector2 center;

        public event EventHandler<SpriteEffectArg> OnStart;
        public event EventHandler<SpriteEffectArg> OnEnd;

        public float Width
        {
            set;
            get;
        }

        public float Height
        {
            set;
            get;
        }

        public Vector2 Position
        {
            get;
            set;
        }

        public Texture2D Texture
        {
            get;
            set;
        }

        public float Orientation
        {
            get;
            set;
        }

        public Color Color
        {
            get;
            set;
        }

        public float Scale
        {
            get;
            set;
        }

        public Vector2 Center
        {
            get
            {
                return Position + new Vector2(Width / 2.0f, Height / 2.0f);
            }
            set
            {
                center = value;
                Position = value - new Vector2(Width / 2.0f, Height / 2.0f);
            }
        }

        public Sprite()
        {
            Scale = 1.0f;
        }
 
        public virtual void Draw(SpriteBatch spriteBatch) 
        {
           
            spriteBatch.Draw(Texture, Position, null, Color, Orientation, Vector2.Zero, Scale,SpriteEffects.None, 0);
            foreach (var sprite in childSprites)
            {
                sprite.Draw(spriteBatch);
            }
        }

        public void AddChildSprite(ISprite sprite) 
        {
            childSprites.Add(sprite);
        }

        public void AttachSpriteEffect(ISpriteEffect spriteEffect)
        {
            
            spriteEffect.Sprite = this;
            
            spriteEffect.OnStart += (_sender, _args)
                =>
                {
                    if (OnStart != null)
                        OnStart(this, new SpriteEffectArg(_sender as ISpriteEffect));
                };
            spriteEffect.OnEnd += (_sender, _args)
                =>
                {
                    if (OnEnd != null)
                        OnEnd(this, new SpriteEffectArg(_sender as ISpriteEffect));
                };

                spriteEffects.Add(spriteEffect);

        }

        //public void OnSpriteEffectStart(Object sender, EventArgs)
        //{
        //    if(OnStart!=null)
        //        OnStart(this, new SpriteEffectArg(_sender as ISpriteEffect));
        //}
        public void DetachSpriteEffect(ISpriteEffect spriteEffect)
        {
            spriteEffects.Remove(spriteEffect);
        }

        public void Update(GameTime gameTime)
        {


            // Update to effect might remove it from spriteEffects
            // So a reverse for loop is used

            for (int i = spriteEffects.Count-1; i >= 0; i--)
            {
                spriteEffects[i].Update(gameTime);
            }

        }

        public void RemoveAllSpriteEffects()
        {
           spriteEffects.Clear();

        }
    }
}
